<!--
 * new page
 * @author: YK
 * @since: 2024-01-24
 * index.vue
-->
<template>
  <el-table
    v-bind="$attrs"
    :data="data"
    v-loading="isLoading"
    :element-loading-text="loadingText"
    :element-loading-spinner="loadingSvg"
    :element-loading-svg-view-box="loadingSvgViewBox"
    :element-loading-background="loadingBackground"
  >
    <template v-for="(item, key) in options" :key="key">
      <el-table-column
        :label="item.label"
        :align="item.align"
        :width="item.width"
      >
        <template #default="scope">
          <template v-if="scope.$index + '-' + scope.column.id == currentCell">
            <div style="display: flex; align-items: center">
              <el-input
                size="small"
                v-model="scope.row[item.prop]"
                placeholder=""
              ></el-input>
              <div @click="currentCell = ''">
                <!-- 自定义图标 -->
                <slot
                  name="eidtCell"
                  v-if="$slots.eidtCell"
                  :scope="scope"
                ></slot>
                <div class="icons" v-else>
                  <!-- 确定图标 -->
                  <component
                    class="check"
                    @click="saveCell(scope)"
                    :is="`el-icon${toLine(saveIcon)}`"
                  ></component>
                  <!-- 关闭图标 -->
                  <component
                    class="close"
                    @click="cancelCell(scope)"
                    :is="`el-icon${toLine(cancelIcon)}`"
                  ></component>
                </div>
              </div>
            </div>
          </template>
          <template v-else>
            <slot v-if="item.slot" :name="item.slot" :scope="scope"></slot>
            <span v-else>{{ scope.row[item.prop] }} </span>
            <el-icon-edit
              class="edit"
              @click="editHandle(scope)"
              v-if="item.edit"
            >
            </el-icon-edit>
          </template>
        </template>
      </el-table-column>
    </template>
  </el-table>
  <div
    class="pagination"
    v-if="pagination"
    :style="{ justifyContent: paginationAlignJustify }"
  >
    <el-pagination
      :current-page="currentPage"
      :page-size="pageSize"
      :page-sizes="pageSizes"
      :small="small"
      :disabled="disabled"
      :background="background"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<script setup lang="ts">
import { TableOptions } from "./types";
import { ref, watch, computed } from "vue";
import { toLine } from "../../../utils";

const props = withDefaults(
  defineProps<{
    options: TableOptions[];
    data: any[]; //表格数据
    loading?: boolean; //是否加载
    loadingText?: string; //加载文字
    loadingSpinner?: string; //加载图标
    loadingBackground?: string; //加载背景色
    loadingSvg: string; //自定义加载图标
    loadingSvgViewBox: string; //自定义加载图标viewBox
    saveIcon: string; //保存图标
    cancelIcon: string; //取消图标
    currentPage: number | string; //当前页数
    pageSizes: number[]; //每页显示条目个数
    pageSize: number | string; //每页显示条目个数
    total: number | string; //总条数
    disabled: boolean; //分页是否禁用
    small: boolean; //分页是否使用小型样式
    background: boolean; //分页是否使用背景色
    pagination: boolean; //是否显示分页
    paginationAlign: "center" | "left" | "right"; //分页是否居中
  }>(),
  {
    options: () => [],
    data: () => [],
    loadingText: "加载中...",
    loadingSvg: `
        <path class="path" d="
          M 30 15
          L 28 17
          M 25.61 25.61
          A 15 15, 0, 0, 1, 15 30
          A 15 15, 0, 1, 1, 27.99 7.5
          L 15 15
        " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
      `,
    loadingSvgViewBox: "0 0 48 48",
    loadingBackground: "rgba(0, 0, 0,.8)",
    loadingSpinner: "spinner",
    saveIcon: "Check",
    cancelIcon: "Close",
    currentPage: 1, //当前页数
    pageSizes: () => [10, 20, 30, 40], //每页显示条目个数
    pageSize: 10, //每页显示条目个数
    total: 0, //总条数
    disabled: false, //分页是否禁用
    small: false, //分页是否使用小型样式
    background: true, //分页是否使用背景色
    pagination: true, //是否显示分页
    paginationAlign: "center",
  }
);
const emit = defineEmits<{
  (e: "saveCell", scope: any): void;
  (e: "cancelCell", scope: any): void;
  (e: "handleSizeChange", val: number): void;
  (e: "handlePageChange", val: number): void;
}>();
//加载
const isLoading = ref(props.loading || false);
watch(
  () => props.loading,
  () => {
    isLoading.value = props.loading;
  }
);
//当前点击的单元格
const currentCell = ref<string>("");
//点击编辑图标
const editHandle = (scope: any) => {
  //唯一标识
  currentCell.value = scope.$index + "-" + scope.column.id;
};
const saveCell = (scope: any) => {
  emit("saveCell", scope);
};
const cancelCell = (scope: any) => {
  emit("cancelCell", scope);
};
//当前页数的改变
const handleSizeChange = (val: number) => {
  emit("handleSizeChange", val);
};
//当前页的改变
const handleCurrentChange = (val: number) => {
  emit("handlePageChange", val);
};
const paginationAlignJustify = computed(() => {
  return props.paginationAlign === "right"
    ? "flex-end"
    : props.paginationAlign === "left"
    ? "flex-start"
    : "center";
});
</script>

<style scoped lang="scss">
.edit {
  width: 1em;
  height: 1em;
  position: relative;
  top: 2px;
  left: 4px;
  cursor: pointer;
}
.icons {
  display: flex;
  margin-left: 4px;

  svg {
    width: 1em;
    height: 1em;
    cursor: pointer;
  }
  .check {
    color: rgb(15, 221, 84);
  }
  .close {
    color: rgb(202, 31, 31);
  }
}
.pagination {
  display: flex;
  margin-top: 16px;
}
</style>
